import {TinyPluginFactory} from "./tiny-plugin-factory";
import {Editor} from "tinymce";
import {DomUtil, ElementAttribute} from "./dom-util";

export const custom_select_flag = "custom-select-plus";
export const custom_select_flag_value = "custom-select-plus";

/**
 */
export class CustomSelectionPlus implements TinyPluginFactory {
  creat = (editor: Editor): void => {

    // select 的 change 处理器
    const selectChangeEventCreate = () => {
      return (e: Event) => {
        console.log(e);
        const target = e.target as HTMLSelectElement;
        const selectedIndex = target.selectedIndex;
        const options = target.options;

        for (let i = 0; i < options.length; i++) {
          options[i].removeAttribute('selected');
        }
        options[selectedIndex].setAttribute('selected', 'true');
      }
    };


    function contentLoad(event) {

      const target = event.target.dom;
      const selects = target.doc.body.querySelectorAll(`select[${custom_select_flag}=${custom_select_flag_value}]`);
      for (let i = 0; i < selects.length; i++) {
        selects[i].addEventListener("change", selectChangeEventCreate())
      }

    }

    // 在setContent时绑定
    editor.on('SetContent', contentLoad);

    tinymce.PluginManager.add('customSelectionPlus', function (editor) {
      const openDialog = function () {
        const optionData: OptionData[] = [];

        // create select dom
        const getSelectDom = function (isFullWidth = true) {
          const options: HTMLOptionElement[] = [];
          options.push(DomUtil.createOption('请选择', '', []));
          for (let i = 0; i < optionData.length; i++) {
            options.push(DomUtil.createOption(optionData[i].label, optionData[i].value, []));
          }

          const selectAttr: ElementAttribute[] = [];
          const style = new ElementAttribute();
          style.attName = 'style';
          style.attValue = `width: ${isFullWidth ? '100%' : 'auto'}`;
          selectAttr.push(style);

          const cus = new ElementAttribute();
          cus.attName = custom_select_flag;
          cus.attValue = custom_select_flag_value;
          selectAttr.push(cus);

          return DomUtil.createSelect("select", options, selectAttr);

        };

        // create select html
        const getSelectHtml = function (isFullWidth = true) {
          return getSelectDom(isFullWidth).outerHTML;
        };

        // create tinymce grid panel component
        const getOptionList = function () {
          const optionItems = [];
          for (let i = 0; i < optionData.length; i++) {
            const row = {type: 'grid', columns: 2};
            const items = [];
            const htmlpanel = {
              type: 'htmlpanel',
              html: `<span><span>${optionData[i].label}</span>:<span>${optionData[i].value}</span></span>`
            };
            items.push(htmlpanel);
            const button = {
              type: 'button',
              text: '删除',
              primary: true,
              name: optionData[i].id,
              disabled: false,
              borderless: false,
            };
            items.push(button);
            row['items'] = items;
            optionItems.push(row);
          }
          return optionItems;
        };


        // 在组件初始化时绑定 change 处理器

        const getConfig = function () {
          return {
            title: "配置自定义选择框",
            size: 'large',
            body: {
              type: 'panel',
              items: [
                {
                  type: 'grid',
                  columns: 2,
                  name: 'first',
                  items: [
                    {
                      type: 'label',
                      label: '配置',
                      items: [
                        {
                          type: 'input', // component type
                          name: 'selection-name', // identifier
                          inputMode: 'text',
                          placeholder: '名字', // placeholder text for the input
                          maximized: false // grow width to take as much space as possible
                        }, {
                          type: 'label',
                          label: '选项',
                          items: getOptionList()
                        }, {
                          type: 'bar',
                          items: [
                            {
                              type: 'input',
                              name: 'option-add-input-label',
                              inputMode: 'text',
                              placeholder: '显示名',
                              maximized: false
                            },
                            {
                              type: 'input',
                              name: 'option-add-input-value',
                              placeholder: '值',
                              inputMode: 'text',
                              maximized: false
                            },
                            {
                              type: 'button', // component type
                              text: '添加',
                              primary: true,
                              name: 'option-add-button',
                              disabled: false,
                              borderless: false,
                            }
                          ]
                        }
                      ]
                    }, {
                      type: 'label',
                      label: '预览',
                      items: [
                        {
                          type: 'htmlpanel', // component type
                          html: getSelectHtml()
                        }
                      ]
                    }
                  ]
                },
              ]
            },
            buttons: [
              {
                type: 'submit',
                text: '保存',
                name: 'save-operation'
              }
            ],

            onAction: function (dialogApi, actionData) {
              if ("option-add-button" === actionData.name) {
                // 添加option
                const data = dialogApi.getData();
                const thisOption = new OptionData();
                thisOption.id = Math.random() + '';
                thisOption.value = data['option-add-input-value'];
                thisOption.label = data['option-add-input-label'];

                if (!thisOption.value || !thisOption.label) {
                  editor.windowManager.alert(`"显示名" 与 "值" 都需要填写！`, null, null);
                  return
                }
                optionData.push(thisOption);
                dialogApi.redial(getConfig());
              } else {
                // 删除option
                for (let i = 0; i < optionData.length; i++) {
                  if (optionData[i].id === actionData.name) {
                    optionData.splice(i, 1);
                  }
                }
                dialogApi.redial(getConfig());
              }
            },
            onChange: function (dialogApi, dialogData) {
              if (dialogData.name === 'option-add-input-label') {
                dialogApi.setData({'option-add-input-value': dialogApi.getData()['option-add-input-label']});
              }
            },
            onSubmit: function (dialogApi) {

              editor.focus();
              const selectNode = editor.selection.getNode();
              selectNode.addEventListener("change", selectChangeEventCreate());
              const lastChild = selectNode.lastChild;
              if (lastChild.nodeName === 'BR') {
                // 这里在append 之前还要去掉p最开始的br元素，因为空行自带一个 br 元素。要不然总有空行
                lastChild.insertAdjacentElement('beforebegin', getSelectDom(false));
                // editor.insertContent(" ");
                editor.selection.setCursorLocation(lastChild);
              } else {
                // 这里就不用去掉br ，因为有内容，但是这里要在插入构建 的 元素后要额外插入一 个空的 TextNode ,用于将编辑器的光标位于这个空的TextNode处；
                selectNode.append(getSelectDom(false));
                const textNode = document.createTextNode(" ");
                selectNode.append(textNode);
                editor.selection.setCursorLocation(textNode);
              }
              dialogApi.close();
            }
          }
        };
        editor.windowManager.open(getConfig());
      };

// 注册一个工具栏按钮名称
      editor.ui.registry.addButton('customSelectionPlus', {
        text: '高级自定义选择框',
        onAction: function () {
          openDialog();
        }
      });

// 注册一个菜单项名称 menu/menubar
      editor.ui.registry.addMenuItem('customSelectionPlus', {
        text: '高级自定义选择框',
        onAction: function () {
          openDialog();
        }
      });

      return {
        getMetadata: function () {
          return {
            //插件名和链接会显示在“帮助”→“插件”→“已安装的插件”中
            name: "高级自定义选择框",//插件名称
            url: "gitee.com/Z_xw", //作者网址
          };
        }
      };
    });
  };
}

class OptionData {
  label: string;
  value: string;
  id: string;
}
